package com.itany.corejava.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author 石小俊
 * @version 1.0
 * @date 2023年03月17日 13:31
 * 日期工具类
 */
public class DateUtil {

    /**
     * 将日期转换成指定格式的字符串
     *
     * @param date    需要转换的日期值
     * @param pattern 指定的字符串格式
     * @return 转换后的字符串
     */
    public static String toString(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 将日期转换成默认格式的字符串
     * @param date 需要转换的日期值
     * @return 转换后的字符串
     * @see DateUtilConstant
     */
    public static String toString(Date date) {
        return toString(date, DateUtilConstant.DATE_DEFAULT_PATTERN);
    }

    /**
     * 将指定格式的字符串转换成日期类型
     * @param s       需要转换的字符串
     * @param pattern 字符串的格式
     * @return 返回转换后的日期
     * @throws ParseException 转换失败后抛出的异常
     */
    public static Date toDate(String s, String pattern) throws ParseException {
        return new SimpleDateFormat(pattern).parse(s);
    }

    /**
     * 将默认格式的字符串转换成日期类型
     * @param s 需要转换的字符串
     * @return 返回转换后的日期
     * @throws ParseException 转换失败后抛出的异常
     * @see DateUtilConstant
     */
    public static Date toDate(String s) throws ParseException {
        return toDate(s, DateUtilConstant.DATE_DEFAULT_PATTERN);
    }


    /**
     * 计算指定日期的下一天
     * @param date 指定日期
     * @return 返回指定日期的下一天
     */
    public static Date getNextDay(Date date) {
        long time = date.getTime() + 24 * 60 * 60 * 1000;
        return new Date(time);
    }

    /**
     * 计算两个日期之间相隔的天数
     * 不足的一天不算
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 返回整数的天数
     */
    public static int getDuringDay(Date startDate, Date endDate) {
        // 可以通过毫秒数相减的方式计算
        long count = endDate.getTime() - startDate.getTime();
        int day = (int) (count / (24 * 60 * 60 * 1000));
        return day;
    }

    /**
     * 计算两个日期之间相隔的天数
     * 不足一天的以一天算
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 返回整数的天数
     */
    public static int getDuringDay2(Date startDate, Date endDate) {
        int day = 0;
        while (startDate.before(endDate)) {
            startDate = getNextDay(startDate);
            day++;
        }
        return day;
    }

    /**
     * 获取指定日期中年、月、日、时、分、秒的值
     * @param date  日期值
     * @param field 获取的日期中哪一个部分的值
     * @return 返回指定部位的值
     * @see DateUtilConstant
     */
    public static int get(Date date, int field) {
        String s = toString(date);
        // 通过正则表达式匹配遇到-、空格或者:都进行分割
        String[] arr = s.split("-|\\s|:");
        return Integer.parseInt(arr[field]);
    }


    /**
     * 根据指定的年份与月份计算天数
     * 方式一:通过设置这一年这个月的最后一天获取当前天数
     * @param year  年份
     * @param month 月份
     * @return 返回这一年这个月共有多少天
     */
    public static int getDay(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        // 设置这一年这个月的最后一天获取当前天数,其值就是这个月共有多少天
        // 此时没有办法直接确定天数
        // 但是可以确定下一个月的第一天的前一天就是这个月的最后一天
        // 设置下一个月
        // calendar.set(Calendar.MONTH,month - 1 + 1);
        calendar.set(Calendar.MONTH, month);
        // 设置第一天的前一天
        // calendar.set(Calendar.DATE,1-1);
        calendar.set(Calendar.DATE, 0);
        return calendar.get(Calendar.DATE);

    }

    /**
     * 根据指定的年份与月份计算天数
     * 方式二:通过日历对象提供的方法getActualMaximum直接获取最大值
     * @param year  年份
     * @param month 月份
     * @return 返回这一年这个月共有多少天
     */
    public static int getDay2(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.YEAR, year);
        return calendar.getActualMaximum(Calendar.DATE);
    }
}
